package com.lin.poweradapter;
import android.support.annotation.CallSuper;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.RecyclerView;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
*
* Created by lin18 on 2017/4/8.
*/
public abstract class SingleAdapter<T, VH extends PowerViewHolder> extends AnimatorAdapter<VH>
implements DataLoadingCallbacks, ItemTouchHelperAdapter {
public final static int LOAD_MORE = -777;
public final static int HEADER = -778;
public final static int FOOTER = -779;
private boolean isLoadMore = false;
private boolean showLoadingMore = false, showHeader = false, showFooter = false;
@Nullable
public OnItemClickListener mItemClickListener;
@Nullable
public OnItemLongClickListener mItemLongClickListener;
@Nullable
public OnStartDragListener mDragStartListener;
@NonNull
private List<T> items;
public SingleAdapter(@NonNull List<T> items) {
this(null, items);
}
public SingleAdapter(@Nullable Object listener) {
this(listener, new ArrayList<T>());
}
public SingleAdapter(@Nullable Object listener, @NonNull List<T> items) {
super();
this.items = items;
addListener(listener);
}
@CallSuper
public void addListener(@Nullable Object listener) {
if (listener instanceof OnItemClickListener) {
mItemClickListener = (OnItemClickListener) listener;
}
if (listener instanceof OnItemLongClickListener) {
mItemLongClickListener = (OnItemLongClickListener) listener;
}
if (listener instanceof OnStartDragListener) {
mDragStartListener = (OnStartDragListener) listener;
}
}
@Override
public long getItemId(int position) {
final int type = getItemViewType(position);
if (type == LOAD_MORE || type == HEADER || type == FOOTER)
return type;
return getItem(position).hashCode();
}
@Override
public int getItemViewType(int position) {
if (showHeader && position == 0)
return HEADER;
else if (getDataItemCount() > 0 && position < getItemCountContainHeader())
return super.getItemViewType(position);
else if (showFooter && position == getItemCountContainHeader())
return FOOTER;
else if (showLoadingMore)
return LOAD_MORE;
return -1;
}
int getItemCountContainHeader() {
return getDataItemCount() + (showHeader ? 1 : 0);
}
int getLoadingMoreItemPosition() {
return showLoadingMore ? (getItemCount() > 0 ? getItemCount() - 1 : 0) : RecyclerView.NO_POSITION;
}
public void setLoadMore(boolean isLoadMore) {
this.isLoadMore = isLoadMore;
}
@Override
public boolean isDataLoading() {
return isLoadMore;
}
@Override
public void dataStartedLoading() {
if (showLoadingMore) return;
showLoadingMore = true;
notifyItemInserted(getLoadingMoreItemPosition());
}
@Override
public void dataFinishedLoading() {
if (!showLoadingMore) return;
final int loadingPos = getLoadingMoreItemPosition();
showLoadingMore = false;
notifyItemRemoved(loadingPos);
}
public void setShowHeader(boolean showHeader) {
this.showHeader = showHeader;
notifyItemInserted(0);
}
public void setShowFooter(boolean showFooter) {
this.showFooter = showFooter;
notifyItemInserted(getItemCount());
}
@Override
public VH onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == HEADER)
return getHeaderHolder(parent);
else if (viewType == FOOTER)
return getFooterHolder(parent);
else if (viewType == LOAD_MORE)
return getLoadingMoreHolder(parent);
else
return onCreateVHolder(parent, viewType);
}
protected VH getLoadingMoreHolder(ViewGroup parent) {
return (VH) new PowerViewHolder(parent, R.layout.progress_item);
}
protected VH getHeaderHolder(ViewGroup parent) {
return null;
}
protected VH getFooterHolder(ViewGroup parent) {
return null;
}
public abstract VH onCreateVHolder(ViewGroup parent, int viewType);
public abstract void onBindVHolder(final VH holder, final int position);
@Override
public void onBindViewHolder(final VH holder, final int position) {
super.onBindViewHolder(holder, position);
if (getItemViewType(position) == LOAD_MORE) {
} else if (getItemViewType(position) == HEADER) {
} else if (getItemViewType(position) == FOOTER) {
} else {
onBindVHolder(holder, position);
setListener(holder, position);
}
}
@CallSuper
void setListener(final VH holder, final int position) {
holder.getContentView().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onItemClick(v, holder);
}
});
holder.getContentView().setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return onItemLongClick(v, holder);
}
});
}
@CallSuper
protected void onItemClick(View v, VH holder) {
if (mItemClickListener != null)
mItemClickListener.onItemClick(v, holder.getAdapterPosition());
}
@CallSuper
protected boolean onItemLongClick(View v, VH holder) {
if (mItemLongClickListener != null)
return mItemLongClickListener.onItemLongClick(v, holder.getAdapterPosition());
return false;
}
@Override
public void onViewRecycled(VH holder) {
super.onViewRecycled(holder);
}
@Override
public boolean onFailedToRecycleView(VH holder) {
return super.onFailedToRecycleView(holder);
}
@Override
public void onViewAttachedToWindow(VH holder) {
super.onViewAttachedToWindow(holder);
}
@Override
public void onViewDetachedFromWindow(VH holder) {
super.onViewDetachedFromWindow(holder);
}
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
super.onDetachedFromRecyclerView(recyclerView);
}
protected void setTouchDragListener(final View view, final RecyclerView.ViewHolder viewHolder) {
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
if (mDragStartListener != null)
mDragStartListener.onStartDrag(viewHolder);
}
return false;
}
});
}
protected void setLongClickDragListener(final View view, final RecyclerView.ViewHolder viewHolder) {
view.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (mDragStartListener != null)
mDragStartListener.onStartDrag(viewHolder);
return true;
}
});
}
@Override
public boolean isSelectable(@IntRange(from = 0) int position) {
return false;
}
public int getDataItemCount() {
return items == null ? 0 : items.size();
}
@Override
public int getItemCount() {
int extra = 0;
if (showLoadingMore)
extra++;
if (showHeader)
extra++;
if (showFooter)
extra++;
return getDataItemCount() + extra;
}
@NonNull
public List<T> getItems() {
return items;
}
public T getItem(@IntRange(from = 0) int position) {
return items.get(position);
}
public T getItemExcludeHeader(@IntRange(from = 0) int position) {
return items.get(showHeader ? position - 1 : position);
}
@CallSuper
public void setItems(@NonNull List<T> items) {
dataFinishedLoading();
this.items = items;
notifyDataSetChanged();
}
@CallSuper
public void remove(@NonNull T elem) {
dataFinishedLoading();
final int position = items.lastIndexOf(elem);
if (position > -1) {
items.remove(position);
notifyItemRemoved(position);
}
}
@CallSuper
public void remove(@IntRange(from = 0) int position) {
dataFinishedLoading();
items.remove(position);
notifyItemRemoved(position);
}
@CallSuper
public void replaceAll(@NonNull List<T> elem) {
dataFinishedLoading();
items.clear();
items.addAll(elem);
notifyDataSetChanged();
}
@CallSuper
public void addAll(@NonNull List<T> elem) {
dataFinishedLoading();
final int size = items.size();
items.addAll(elem);
notifyItemRangeInserted(size, items.size());
}
@CallSuper
public void addData(@IntRange(from = 0) int position, @NonNull List<T> data) {
dataFinishedLoading();
items.addAll(position, data);
notifyItemRangeInserted(position, data.size());
}
@CallSuper
public void add(@NonNull T elem) {
dataFinishedLoading();
items.add(elem);
notifyItemInserted(items.size());
}
@CallSuper
public void add(@IntRange(from = 0) int position, @NonNull T elem) {
dataFinishedLoading();
items.add(position, elem);
notifyItemInserted(position);
}
@CallSuper
public void set(@IntRange(from = 0) int position, @NonNull T elem) {
dataFinishedLoading();
items.set(position, elem);
notifyItemChanged(position);
}
@CallSuper
public void update(@NonNull T elem) {
dataFinishedLoading();
final int index = items.indexOf(elem);
if (index > -1) {
set(index, elem);
}
}
@CallSuper
public void clear() {
dataFinishedLoading();
items.clear();
notifyDataSetChanged();
}
@CallSuper
@Override
public void onItemDismiss(int position) {
items.remove(position);
notifyItemRemoved(position);
}
@CallSuper
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
Collections.swap(items, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
return true;
}
public interface OnItemClickListener {
void onItemClick(View v, int position);
}
public interface OnItemLongClickListener {
boolean onItemLongClick(View v, int position);
}
}